package com.ruoyi.warehouse.controller;

import java.util.List;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.warehouse.domain.DrugWarehouseStock;
import com.ruoyi.warehouse.service.IDrugWarehouseStockService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.warehouse.domain.DrugWarehouseOperate;
import com.ruoyi.warehouse.service.IDrugWarehouseOperateService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 药库操作Controller
 * 
 * @author ruoyi
 * @date 2025-08-22
 */
@RestController
@RequestMapping("/warehouse/drug_warehouse_operate")
public class DrugWarehouseOperateController extends BaseController
{
    @Autowired
    private IDrugWarehouseOperateService drugWarehouseOperateService;
    @Autowired
    private IDrugWarehouseStockService drugWarehouseStockService;

    /**
     * 新增药库操作（入库操作）
     */
    @PreAuthorize("@ss.hasPermi('warehouse:drug_warehouse_operate:add')")
    @Log(title = "药库操作", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody DrugWarehouseOperate drugWarehouseOperate) {
        // 1. 验证操作类型（必须是1=入库或2=出库）
        Integer operateType = drugWarehouseOperate.getOperateType();
        if (operateType == null || (operateType != 1 && operateType != 2)) {
            return error("操作类型必须是1（入库）或2（出库）");
        }

        // 2. 验证数量必须为正数（统一校验，后续根据类型处理正负）
        Long quantity = drugWarehouseOperate.getQuantity();
        if (quantity == null || quantity <= 0) {
            return error("操作数量必须大于0");
        }

        // 3. 根据操作类型更新库存（true=入库，false=出库）
        boolean isInStock = operateType == 1;
        AjaxResult stockResult = updateStock(drugWarehouseOperate, isInStock);
        if (!Integer.valueOf(200).equals(stockResult.get("code"))) {
            return stockResult;
        }

        // 4. 保存操作记录（出库时可将数量存为负数，方便后续统计）
        if (!isInStock) {
            drugWarehouseOperate.setQuantity(-quantity); // 出库数量存为负数
        }

        // 5. 插入操作记录（operateId 若自增则无需手动设置）
        return toAjax(drugWarehouseOperateService.insertDrugWarehouseOperate(drugWarehouseOperate));
    }
    /**
     * 查询药库操作列表
     */
    @PreAuthorize("@ss.hasPermi('warehouse:drug_warehouse_operate:list')")
    @GetMapping("/list")
    public TableDataInfo list(DrugWarehouseOperate drugWarehouseOperate)
    {
        startPage();
        List<DrugWarehouseOperate> list = drugWarehouseOperateService.selectDrugWarehouseOperateList(drugWarehouseOperate);
        return getDataTable(list);
    }

    /**
     * 导出药库操作列表
     */
    @PreAuthorize("@ss.hasPermi('warehouse:drug_warehouse_operate:export')")
    @Log(title = "药库操作", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, DrugWarehouseOperate drugWarehouseOperate)
    {
        List<DrugWarehouseOperate> list = drugWarehouseOperateService.selectDrugWarehouseOperateList(drugWarehouseOperate);
        ExcelUtil<DrugWarehouseOperate> util = new ExcelUtil<DrugWarehouseOperate>(DrugWarehouseOperate.class);
        util.exportExcel(response, list, "药库操作数据");
    }

    /**
     * 获取药库操作详细信息
     */
    @PreAuthorize("@ss.hasPermi('warehouse:drug_warehouse_operate:query')")
    @GetMapping(value = "/{operateId}")
    public AjaxResult getInfo(@PathVariable("operateId") Long operateId)
    {
        return success(drugWarehouseOperateService.selectDrugWarehouseOperateByOperateId(operateId));
    }

    /**
     * 修改药库操作（出库操作）
     */
    @PreAuthorize("@ss.hasPermi('warehouse:drug_warehouse_operate:edit')")
    @Log(title = "药库操作", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody DrugWarehouseOperate drugWarehouseOperate)
    {
        // 验证操作类型是否为出库
        if (drugWarehouseOperate.getOperateType() != 2) {
            return error("修改操作只能是出库操作");
        }

        // 验证数量是否为负数
        if (drugWarehouseOperate.getQuantity() == null || drugWarehouseOperate.getQuantity() <= 0) {
            return error("出库数量必须大于0");
        }

        // 获取原始操作记录
        DrugWarehouseOperate originalOperate = drugWarehouseOperateService.selectDrugWarehouseOperateByOperateId(drugWarehouseOperate.getOperateId());
        if (originalOperate == null) {
            return error("操作记录不存在");
        }

        // 计算数量变化（出库数量应为负数）
        long quantityChange = -drugWarehouseOperate.getQuantity();

        // 更新库存
        AjaxResult stockResult = updateStock(drugWarehouseOperate, false);
        if (!Integer.valueOf(200).equals(stockResult.get("code"))) {
            return stockResult;
        }

        // 更新操作记录
        return toAjax(drugWarehouseOperateService.updateDrugWarehouseOperate(drugWarehouseOperate));
    }

    /**
     * 删除药库操作
     */
    @PreAuthorize("@ss.hasPermi('warehouse:drug_warehouse_operate:remove')")
    @Log(title = "药库操作", businessType = BusinessType.DELETE)
	@DeleteMapping("/{operateIds}")
    public AjaxResult remove(@PathVariable Long[] operateIds)
    {
        return toAjax(drugWarehouseOperateService.deleteDrugWarehouseOperateByOperateIds(operateIds));
    }

    /**
     * 更新库存
     * @param drugWarehouseOperate 操作记录
     * @param isAdd 是否为新增操作（入库）
     * @return AjaxResult
     */
    private AjaxResult updateStock(DrugWarehouseOperate drugWarehouseOperate, boolean isAdd) {
        // 1. 构建查询条件（药库ID + 药品ID）
        DrugWarehouseStock queryStock = new DrugWarehouseStock();
        queryStock.setWarehouseId(drugWarehouseOperate.getWarehouseId());
        queryStock.setDrugId(drugWarehouseOperate.getDrugId());
        List<DrugWarehouseStock> stockList = drugWarehouseStockService.selectDrugWarehouseStockList(queryStock);

        // 2. 处理库存记录不存在的情况
        if (stockList.isEmpty()) {
            // 入库：创建新库存记录
            if (isAdd) {
                DrugWarehouseStock newStock = new DrugWarehouseStock();
                newStock.setWarehouseId(drugWarehouseOperate.getWarehouseId());
                newStock.setDrugId(drugWarehouseOperate.getDrugId());
                newStock.setQuantity(drugWarehouseOperate.getQuantity()); // 直接使用入库数量
                drugWarehouseStockService.insertDrugWarehouseStock(newStock);
                return AjaxResult.success("库存记录创建成功");
            }
            // 出库：库存不存在，无法操作
            else {
                return AjaxResult.error("库存记录不存在，无法执行出库操作");
            }
        }

        // 3. 处理库存记录存在的情况
        DrugWarehouseStock existingStock = stockList.get(0);
        long newQuantity;

        if (isAdd) {
            // 入库操作：库存累加
            newQuantity = existingStock.getQuantity() + drugWarehouseOperate.getQuantity();
        } else {
            // 出库操作：库存递减（先校验是否充足）
            newQuantity = existingStock.getQuantity() - drugWarehouseOperate.getQuantity();
            if (newQuantity < 0) {
                return AjaxResult.error(
                        String.format("库存不足，当前库存: %d，请求出库: %d",
                                existingStock.getQuantity(),
                                drugWarehouseOperate.getQuantity())
                );
            }
        }

        // 4. 更新库存并返回结果
        existingStock.setQuantity(newQuantity);
        int updateRows = drugWarehouseStockService.updateDrugWarehouseStock(existingStock);
        if (updateRows > 0) {
            return AjaxResult.success("库存更新成功", newQuantity);
        } else {
            return AjaxResult.error("库存更新失败，请重试");
        }
    }

}
